In [ ]:
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from tqdm.auto import tqdm, trange
In [ ]:
import plotly.io as pio
pio.renderers.default = "notebook_connected"

def plot_signal(x, t):
    return go.Figure([go.Scatter(y=x, x=t, mode="lines+markers")
                      ]).update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
    )

def plot_freqs(x, f, f_max=10):
    f_idxs = np.abs(f)<f_max
    return go.Figure(go.Scatter(y=x[f_idxs], x=f[f_idxs], mode="lines+markers")).update_layout(
        xaxis_title="Frequency, Hz",
        yaxis_title="Strength",
    )
In [ ]:
def wsinterp(x, xp, fp, left=None, right=None):
    """One-dimensional Whittaker-Shannon interpolation.

    This uses the Whittaker-Shannon interpolation formula to interpolate the
    value of fp (array), which is defined over xp (array), at x (array or
    float).

    Returns the interpolated array with dimensions of x.

    x: t_int
    xp: t_real
    fp: f_real

    """
    scalar = np.isscalar(x)
    if scalar:
        x = np.array(x)
        x.resize(1)
    # shape = (nxp, nx), nxp copies of x data span axis 1
    u = np.resize(x, (len(xp), len(x)))
    # Must take transpose of u for proper broadcasting with xp.
    # shape = (nx, nxp), v(xp) data spans axis 1
    v = (xp - u.T) / (xp[1] - xp[0])
    # shape = (nx, nxp), m(v) data spans axis 1
    m = fp * np.sinc(v)
    # Sum over m(v) (axis 1)
    fp_at_x = np.sum(m, axis=1)

    # Enforce left and right
    if left is None:
        left = fp[0]
    fp_at_x[x < xp[0]] = left
    if right is None:
        right = fp[-1]
    fp_at_x[x > xp[-1]] = right

    # Return a float if we got a float
    if scalar:
        return float(fp_at_x)

    return fp_at_x

Simple signals

In [ ]:
sample_rate_full = 1000  #  Samples per s
sin_freq = 5  # Hz
sin_omega = (2*np.pi)*sin_freq
sin_ts = np.arange(0, 2, 1/sample_rate_full)
# sin_vals = np.sin(sin_omega * sin_ts)

sin_vals = np.exp(1j * sin_omega * sin_ts)
plot_signal(sin_vals.real, sin_ts).show()
In [ ]:
def fft(vals, ts):
    sample_rate = ts.shape[-1]/(ts[-1] - ts[0])
    return np.abs(np.fft.fft(vals)), np.fft.fftfreq(vals.shape[-1])*sample_rate

plot_freqs(*fft(sin_vals, sin_ts)).show()
In [ ]:
# wsinterp with full sample rate
sin_wsint = wsinterp(sin_ts, sin_ts, sin_vals)
plot_signal(sin_wsint.real, sin_ts)
In [ ]:
# wsinterp with smaller sample rate
sample_rates = [50, 10, 6, 5]


# for sample_period in sample_periods:
for sample_rate in sample_rates:
    sample_period = sample_rate_full//sample_rate
    fig = go.Figure()
    sample_ts = sin_ts[::sample_period]
    sample_vals = sin_vals[::sample_period]
    sample_interp = wsinterp(sin_ts, sample_ts, sample_vals)
    fig.add_trace(go.Scatter(y=sin_vals.real, x=sin_ts, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=sample_interp.real, x=sin_ts, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=sample_vals.real, x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Strength",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{sin_freq} Hz"
        ).show()
    plot_freqs(*fft(sample_interp, sin_ts)).update_layout(
        title=f"Sample rate:{sample_rate} Hz; Signal freq:{sin_freq} Hz"
    ).show()

With multipath¶

In [ ]:
sin_freq2 = 6
sin_vals2 = np.exp(1j*2*np.pi*sin_freq2 * sin_ts)
sin_multipath = sin_vals+sin_vals2*0.3
plot_signal(sin_multipath.real, sin_ts).show()
In [ ]:
plot_freqs(*fft(sin_multipath, sin_ts)).show()
In [ ]:
# wsinterp with smaller sample rate
sample_rates = [50, 10, 6, 5]

for sample_rate in sample_rates:
    sample_period = sample_rate_full//sample_rate
    fig = go.Figure()
    sample_ts = sin_ts[::sample_period]
    sample_vals = sin_multipath[::sample_period]
    sample_interp = wsinterp(sin_ts, sample_ts, sample_vals)
    fig.add_trace(go.Scatter(y=sin_multipath.real, x=sin_ts, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=sample_interp.real, x=sin_ts, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=sample_vals.real, x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Strength",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{sin_freq} Hz"
        ).show()
    fig = go.Figure()
    fig.add_trace(go.Scatter(y=np.angle(sin_multipath), x=sin_ts, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=np.angle(sample_interp), x=sin_ts, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=np.angle(sample_vals), x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Phase",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{sin_freq} Hz"
        ).show()
    plot_freqs(*fft(sample_interp, sin_ts)).update_layout(
        title=f"Sample rate:{sample_rate} Hz; Signal freq:{sin_freq} Hz"
    ).show()

Simulator data¶

In [ ]:
from run_experiment import experiments

from distance_determination import get_current_freq, estimate_dist, simulate_signals
from simul.utilities.data import load_experiment
from simul.vis.signals import vis_signals, vis_signals_2d
# from distance_determination import estimate_dist, simulate_signal

exp_name = "full_no_walls"
params = experiments[exp_name]
print(params)
dist, simul_vals_multifreq = simulate_signals(params)

simul_ts = params.tss
simul_vals = simul_vals_multifreq[0,:]
simul_sample_rate = int(1/(simul_ts[1] - simul_ts[0]))
fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals), x=simul_ts, mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

plot_freqs(*fft(simul_vals, simul_ts), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()
Parameters(vel=5, start_pos=10, key_x0=10, scenario_matrix=[1.0, 0.0, 0.0, 0.0], signal_paths=({'type': 'LOS'}, {'type': 'ParralelWall', 'wall_y': 1.0}, {'type': 'ParralelWall', 'wall_y': 4.0}, {'type': 'NormalWall', 'wall_x': 13.0}), n_freq=40, freq_set_type=2, f_pack_len=5, delta_t=0.0003)
                                                                                         
In [ ]:
fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals[simul_ts<1]), x=simul_ts[simul_ts<1], mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

plot_freqs(*fft(simul_vals[simul_ts<1], simul_ts[simul_ts<1]), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()

fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals[simul_ts>6]), x=simul_ts[simul_ts>6], mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

plot_freqs(*fft(simul_vals[simul_ts>6], simul_ts[simul_ts>6]), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()
In [ ]:
# wsinterp with smaller sample rate
sample_rates = [100, 50, 40, 10]
simul_val_block, simul_ts_block = simul_vals[simul_ts>6], simul_ts[simul_ts>6]
for sample_rate in sample_rates:
    sample_period = simul_sample_rate//sample_rate
    fig = go.Figure()
    sample_ts = simul_ts_block[::sample_period]
    sample_vals = simul_val_block[::sample_period]
    sample_interp = wsinterp(simul_ts_block, sample_ts, sample_vals)
    fig.add_trace(go.Scatter(y=simul_val_block.real, x=simul_ts_block, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=sample_interp.real, x=simul_ts_block, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=sample_vals.real, x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Strength",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
        ).show()
    fig = go.Figure()
    fig.add_trace(go.Scatter(y=np.angle(simul_val_block), x=simul_ts_block, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=np.angle(sample_interp), x=simul_ts_block, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=np.angle(sample_vals), x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Phase",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
        ).show()
    plot_freqs(*fft(sample_interp, simul_ts_block), f_max = 50).update_layout(
        title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
    ).show()
In [ ]:
exp_name = "default_full"
params = experiments[exp_name]
print(params)
dist, simul_vals_multifreq = simulate_signals(params)

simul_ts = params.tss
simul_vals = simul_vals_multifreq[0,:]
simul_sample_rate = int(1/(simul_ts[1] - simul_ts[0]))
fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals), x=simul_ts, mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

fig = go.Figure()
fig.add_trace(go.Scatter(y=np.abs(simul_vals), x=simul_ts, mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Amplitude",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()
plot_freqs(*fft(simul_vals, simul_ts), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()
Parameters(vel=5, start_pos=10, key_x0=10, scenario_matrix=[0.2, 0.0, 0.0, 0.6], signal_paths=({'type': 'LOS'}, {'type': 'ParralelWall', 'wall_y': 1.0}, {'type': 'ParralelWall', 'wall_y': 4.0}, {'type': 'NormalWall', 'wall_x': 13.0}), n_freq=40, freq_set_type=2, f_pack_len=5, delta_t=0.0003)
                                                                                         
In [ ]:
fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals[simul_ts<1]), x=simul_ts[simul_ts<1], mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

plot_freqs(*fft(simul_vals[simul_ts<1], simul_ts[simul_ts<1]), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()

fig = go.Figure()
fig.add_trace(go.Scatter(y=np.real(simul_vals[simul_ts>6]), x=simul_ts[simul_ts>6], mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Signal",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

fig = go.Figure()
fig.add_trace(go.Scatter(y=np.abs(simul_vals[simul_ts>6]), x=simul_ts[simul_ts>6], mode="lines", name="Sample points"))
fig.update_layout(
        xaxis_title="Time, s",
        yaxis_title="Amplitude",
        title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
    ).show()

plot_freqs(*fft(simul_vals[simul_ts>6], simul_ts[simul_ts>6]), f_max = 50).update_layout(
    title=f"Sample rate:{simul_sample_rate} Hz; Signal freq:{22} Hz"
).show()
In [ ]:
# wsinterp with smaller sample rate
sample_rates = [100, 50, 40, 10]
simul_val_block, simul_ts_block = simul_vals[simul_ts>6], simul_ts[simul_ts>6]
for sample_rate in sample_rates:
    sample_period = simul_sample_rate//sample_rate
    fig = go.Figure()
    sample_ts = simul_ts_block[::sample_period]
    sample_vals = simul_val_block[::sample_period]
    sample_interp = wsinterp(simul_ts_block, sample_ts, sample_vals)
    fig.add_trace(go.Scatter(y=simul_val_block.real, x=simul_ts_block, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=sample_interp.real, x=simul_ts_block, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=sample_vals.real, x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Strength",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
        ).show()
    fig = go.Figure()
    fig.add_trace(go.Scatter(y=np.angle(simul_val_block), x=simul_ts_block, mode="lines", name="Real"))
    fig.add_trace(go.Scatter(y=np.angle(sample_interp), x=simul_ts_block, mode="lines",  name="Interpolated"))
    fig.add_trace(go.Scatter(y=np.angle(sample_vals), x=sample_ts, mode="markers", name="Sample points"))
    fig.update_layout(
            xaxis_title="Time, s",
            yaxis_title="Phase",
            title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
        ).show()
    plot_freqs(*fft(sample_interp, simul_ts_block), f_max = 50).update_layout(
        title=f"Sample rate:{sample_rate} Hz; Signal freq:{22} Hz"
    ).show()
In [ ]: